﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include<vector>
#include<list>
#include<map>
#include <cassert>
using namespace std;

//struct Point
//{
//	int _x;
//	int _y;
//};
// //{}大括号
//int main()
//{
//	int x1 = 1;
//	int x2 = { 2 };
//	int x4(1);
//
//	//可以省略赋值括号
//	int x3{ 3 };
//	int array1[]{ 1,2,3,4,5 };
//	int array2[5]{ 0 };
//}

//class Date
//{
//public:
//	//explicit Date(int year, int month, int day)
//	Date(int year, int month, int day)
//		:_year(year)
//		, _month(month)
//		, _day(day)
//	{
//		cout << "Date(int year, int month, int day)" << endl;
//	}
//
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//
////int main()
////{
////	Date d1(2022, 1, 1); // old style
////
////	// C++11支持的列表初始化，这里会调用构造函数初始化
////	Date d2 = { 2022, 1, 2 };
////	Date d3 { 2022, 1, 3 };
////
////	return 0;
////}
//
////initializer_list
//int main()
//{
//	vector<int> v1 = { 1,2,3,4,5 };
//	vector<int> v2 = { 10,20,30 };
//	vector<int> v3 = { 10,20,30,1,1,2,2,2,2,2,2,1,1,1,1,1,1,1,1,2,1,1,2 };
//
//	list<int> lt1 = { 1,2,3,4,5 };
//	list<int> lt2 = { 10,20,30 };
//
//	//auto==initializer_list
//	auto i1 = { 10,20,30,1,1,2,2,2,2,2,2,1,1,1,1,1,1,1,1,2,1,1,2 };
//	auto i2 = { 10,20,30 };
//	cout << typeid(i1).name() << endl;
//	cout << typeid(i2).name() << endl;
//
//	initializer_list<int>::iterator it1 = i1.begin();
//	initializer_list<int>::iterator it2 = i2.begin();
//	cout << it1 << endl;
//	cout << it2 << endl;
//	// *it1 = 1;
//
//	initializer_list<int> i3 = { 10,20,30 };
//	initializer_list<int>::iterator it3 = i3.begin();
//	cout << it3 << endl;
//
//	Date d1(2023,5,20);
//	Date d2(2023,5,21);
//	
//	vector<Date> vd1 = {d1, d2};	// initializer_list<Date>
//	vector<Date> vd2 = { Date(2023,5,20), Date(2023,5,21) };
//	vector<Date> vd3 = { {2023,5,20}, {2023,5,20} };
//	
// //等号可省略，但不加有些奇怪
//	map<string, string> dict = { {"sort", "排序"},{"string", "字符串"},{"Date", "日期"} };
//	pair<string, string> kv1 = { "Date", "日期" };
//	pair<string, string> kv2 { "Date", "日期" };
//
//	return 0;
//}

//decltype
//int main()
//{
//	const int x = 1;
//	double y = 2.23;
//	cout << typeid(x * y).name() << endl;
//	decltype(x * y) ret;
//	cout << typeid(ret).name() << endl;
//
//	vector<decltype(x* y)> v;
//	return 0;
//}

/////////左右值引用
//int main()
//{
//	int a = 0;
//	int b = 1;
//	int* p = &a;
//
//	a + b;
//
//	// 左值引用给左值取别名
//	int& ref1 = a;
//
//	// 左值引用给右值取别名
//	// int& ref2 = (a + b);
//	const int& ref2 = (a + b);
//
//	// 右值引用给右值取别名
//	int&& ref3 = (a + b);
//
//	// 右值引用给move后左值取别名
//	//int&& ref4 = a;
//	int&& ref4 = move(a);
//
//	return 0;
//}

//void func(int& a)
//{
//	cout << "void func(int& a)" << endl;
//}
//
//void func(int&& a)
//{
//	cout << "void func(int&& a)" << endl;
//}
//
//int main()
//{
//	int a = 0;
//	int b = 1;
//	func(a);
//	func(a + b);
//}


//namespace bit
//{
//	class string
//	{
//	public:
//		typedef char* iterator;
//		iterator begin()
//		{
//			return _str;
//		}
//
//		iterator end()
//		{
//			return _str + _size;
//		}
//
//		string(const char* str = "")
//			:_size(strlen(str))
//			, _capacity(_size)
//		{
//			//cout << "string(char* str)" << endl;
//
//			_str = new char[_capacity + 1];
//			strcpy(_str, str);
//		}
//
//		// s1.swap(s2)
//		void swap(string& s)
//		{
//			::swap(_str, s._str);
//			::swap(_size, s._size);
//			::swap(_capacity, s._capacity);
//		}
//
//		// 拷贝构造
//		string(const string& s)
//			:_str(nullptr)
//		{
//			cout << "string(const string& s) -- 深拷贝" << endl;
//
//			string tmp(s._str);
//			swap(tmp);
//		}
//
//		// 移动构造（接收右值）
//		string(string&& s)
//			:_str(nullptr)
//		{
//			cout << "string(string&& s) -- 移动拷贝" << endl;
//			swap(s);
//		}
//
//		// 赋值重载
//		string& operator=(const string& s)
//		{
//			cout << "string& operator=(string s) -- 深拷贝" << endl;
//			string tmp(s);
//			swap(tmp);
//
//			return *this;
//		}
//
//		~string()
//		{
//			delete[] _str;
//			_str = nullptr;
//		}
//
//		char& operator[](size_t pos)
//		{
//			assert(pos < _size);
//			return _str[pos];
//		}
//
//		void reserve(size_t n)
//		{
//			if (n > _capacity)
//			{
//				char* tmp = new char[n + 1];
//				strcpy(tmp, _str);
//				delete[] _str;
//				_str = tmp;
//
//				_capacity = n;
//			}
//		}
//
//		void push_back(char ch)
//		{
//			if (_size >= _capacity)
//			{
//				size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
//				reserve(newcapacity);
//			}
//
//			_str[_size] = ch;
//			++_size;
//			_str[_size] = '\0';
//		}
//
//		//string operator+=(char ch)
//		string& operator+=(char ch)
//		{
//			push_back(ch);
//			return *this;
//		}
//
//		string operator+(char ch)
//		{
//			string tmp(*this);
//			tmp += ch;
//			return tmp;
//		}
//
//		const char* c_str() const
//		{
//			return _str;
//		}
//	private:
//		char* _str;
//		size_t _size;
//		size_t _capacity; // 不包含最后做标识的\0
//	};
//
//	bit::string to_string(int value)
//	{
//		bool flag = true;
//		if (value < 0)
//		{
//			flag = false;
//			value = 0 - value;
//		}
//
//		bit::string str;
//		while (value > 0)
//		{
//			int x = value % 10;
//			value /= 10;
//
//			str += ('0' + x);
//		}
//
//		if (flag == false)
//		{
//			str += '-';
//		}
//
//		std::reverse(str.begin(), str.end());
//		return str;
//		//return move(str);加了move也可以正常运行，不加编译器自动加上move。
//	}
//}
// 左值引用：直接减少拷贝。1、左值引用传参  2、传引用返回。（函数内的局部对象，不能用引用返回）

//int main()
//{
// //编译器优化看不到调用移动构造
//	bit::string valStr = bit::to_string(1234);
//	//cout << valStr.c_str() << endl;
//	
//	return 0;
//}


//int main()
//{
//	std::string s1("hello");
//	move(s1);//move的返回值是右值
//	std::string s3 = s1;
//
//	return 0;
//}
//int main()
//{
//	std::string s1("hello");
//	std::string s2 = s1;
//	std::string s3 = move(s1);
//
//	return 0;
//}

//为什么第一段s1的值还存在，第二段代码s1的值不存在？
/*
在第一段代码中，虽然使用了std::move(s1)，但是并没有将其返回值赋值给任何变量，
也没有对其进行其他操作。因此，s1的值仍然存在，没有发生实际的资源转移。

在第二段代码中，使用了std::string s2 = s1;进行了拷贝构造，这会创建一个新的字符串对象s2，
并将s1的值复制到s2中。而在std::string s3 = move(s1);这一行，
使用了std::move(s1)将s1的值转移到s3中，发生了实际的资源转移。

所以，第一段代码中s1的值仍然存在，因为没有进行实际的资源转移操作。
而第二段代码中，s1的值不存在，因为它的值已经被转移给了s3。

需要注意的是，使用std::move只是将对象标记为可移动的，实际的资源转移需要
在移动构造函数或移动赋值运算符中进行。如果没有对转移后的对象进行操作，
原对象的值仍然存在。只有在实际的资源转移操作发生后，原对象的值才会被移动或无效化。*/


//int main()
//{
//	list<bit::string> It;
//	//bit::string s1("hello world");
//
//	//It.push_back(s1);//深拷贝
//	//It.push_back(move(s1));//调用移动构造
//	/*在给定的代码中，lt是一个std::list<bit::string>类型的容器，s1是一个bit::string对象。
//
//	在lt.push_back(s1);这行代码中，将s1作为左值传递给push_back函数，
//	这会调用std::list的拷贝构造函数，将s1的副本插入到容器中。
//
//	而在lt.push_back(move(s1));这行代码中，使用std::move将s1转换为右值引用，
//	并将其作为右值传递给push_back函数。这会调用std::list的移动构造函数，
//	将s1的资源所有权转移到容器中，而不进行拷贝操作。
//
//	从效率的角度来看，lt.push_back(move(s1));的效率可能会更高。
//	这是因为移动构造函数通常比拷贝构造函数更高效，特别是对于大型对象或包含大量资源的对象。
//	通过使用移动构造函数，可以避免不必要的拷贝操作，提高性能和效率。*/
//	
//	
//	It.push_back(bit::string("hello world"));//匿名对象>>右值
//	It.push_back("hello world");
//	
//	
//	
//	
//	
//	return 0;
//}



//void Fun(int& x) { cout << "左值引用" << endl; }
//void Fun(const int& x) { cout << "const 左值引用" << endl; }
//void Fun(int&& x) { cout << "右值引用" << endl; }
//void Fun(const int&& x) { cout << "const 右值引用" << endl; }
//
//template<typename T>
//void PerfectForward(T&& t)
//{
//	Fun(t);
//}
//int main()
//{
//	//标注类型
//	PerfectForward(10);
//	int a;
//	PerfectForward(a);
//	PerfectForward(std::move(a)); // 右值
//	const int b = 8;
//	PerfectForward(b);
//	PerfectForward(std::move(b)); // const 右值
//	return 0;
//}



//template<class T>
//void ShowList(const T& t)
//{
//	cout << t << endl;
//}
//
//template<class T ,class ...Args>
//void ShowList(T value, Args... args)
//{
//	cout << value << " ";
//	ShowList(args...);
//}
//
//template<class T>
//void PrintArg(T t)
//{
//	cout << t << " ";
//}
//
//template<class ...Args>
//void ShowList2(Args... args)
//{
//	int arr[] = { (PrintArg(args),0)... };
//	cout << endl;
//}
//
//int main()
//{
//	ShowList(1);
//	ShowList(1, 'A');
//	ShowList(1, 'A', std::string("sort"));
//	cout << endl;
//	ShowList2(1);
//	ShowList2(1, 'A');
//	ShowList2(1, 'A', std::string("sort"));
//}


//template<typename... Args>
//double sumHelper(double total)
//{
//	return total;
//}
//
//template<typename T,typename... Args>
//double sumHelper(T first, Args... args)
//{
//	return sumHelper(first + sumHelper(args...));
//}
//
//template<typename... Args>
//double sum(Args... args)
//{
//	return sumHelper(static_cast<double>(args)...);
//}
//
//int main() {
//	std::cout << "Sum of 1, 2, 3, 4, 5 is: " << sum(1, 2, 3, 4, 5) << std::endl;
//	std::cout << "Sum of 3.14, 2.71, 1.618 is: " << sum(3.14, 2.71, 1.618) << std::endl;
//	return 0;
//}
#include <utility>
template <class T>
void showlist(const T& t)
{
	cout << t << endl;
}

template<class T,class ...Arg>
void showlist(T value, Arg... args)
{
	cout << value << " ";
	showlist(args...);
}


template <class T>
void PrintArg(T t)
{
	cout << t << " ";
}

template<class ...Args>
void showlist2(Args... args)
{
	int a[] = { (PrintArg(args),0)... };
	cout << endl;
}


//int main()
//{
//
//
//	/*showlist(1);
//	showlist2(1);
//	showlist(1, 'a');
//	showlist2(1, 'a');
//	showlist(1, 'a', std::string("sss"));
//	showlist2(1, 'a',  std::string("sss"));
//	cout << "test";*/
//}




//// 基础函数，用于结束递归
//template<typename... Args>
//double sumHelper(double total)
//{
//	return total;
//}
//
//// 可变参数模板函数，递归地累加参数
//template<typename T, typename... Args>
//double sumHelper(T first, Args... args)
//{
//	return sumHelper(first + sumHelper(args...));
//}
//
//// 入口函数，开始递归求和
//template<typename... Args>
//double sum(Args... args)
//{
//	return sumHelper(static_cast<double>(args)...);
//}

//int main()
//{
//	std::cout << "Sum of 1, 2, 3, 4, 5 is: " << sum(1, 2, 3, 4, 5) << std::endl;
//	std::cout << "Sum of 3.14, 2.71, 1.618 is: " << sum(3.14, 2.71, 1.618) << std::endl;
//	return 0;
//}